﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Microsoft.Xna.Framework;
using SoulDoorEngine.Framework.Components;
using SoulDoorEngine.Framework.Screens;

namespace SoulDoorEngine.Framework.Components
{
    public class ComponentCollection : Collection<Component>
    {
        private Screen _Owner;
        private List<int> _DrawOrderIndex = new List<int>();

        /// <summary>
        /// 绘制顺序，包含了所有该集合中组件的序号，引擎将按照此顺序进行绘制
        /// </summary>
        private List<int> DrawOrderIndex
        {
            get { return _DrawOrderIndex; }
            set { _DrawOrderIndex = value; }
        }
        
        /// <summary>
        /// 组件集合拥有者
        /// </summary>
        public Screen Owner
        {
            get { return _Owner; }
            set { _Owner = value; }
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="owner">该组件集合拥有者（屏幕实例）</param>
        public ComponentCollection(Screen owner)
        {
            this.Owner = owner;
        }

        protected override void InsertItem(int index, Component item)
        {
            //********************************************
            //***注意此处对Owner的判断是否会导致多次更新/绘制***
            //********************************************
            if (item.Parent == this.Owner)
            {
                return;//新增加，与原版本不同
            }
            if (item.Parent != null && item.Parent != this.Owner)
            {
                item.Parent.Components.Remove(item);
            }
            item.Parent = this.Owner;
            item.DrawOrderChanged += new ComponentDrawOrderChangedEventHandler(item_DrawOrderChanged);
            base.InsertItem(index, item);
            this.UpdateDrawPosition(item);
        }

        void item_DrawOrderChanged(object sender, ComponentDrawOrderChangedEventArgs e)
        {
            this.UpdateDrawPosition(e.Component);
        }

        /// <summary>
        /// 更新组件绘制顺序
        /// </summary>
        /// <param name="component"></param>
        private void UpdateDrawPosition(Component component)
        {
            int order = component.DrawOrder;
            int location = Items.IndexOf(component);
            //移除绘制顺序索引中相同的项
            if (DrawOrderIndex.Contains(location))
            {
                DrawOrderIndex.Remove(location);
            }

            int i = 0;
            if (order > 0)
            {
                for (; i < DrawOrderIndex.Count; ++i)
                {
                    if (Items[DrawOrderIndex[i]].DrawOrder >= order)
                    {
                        break;
                    }
                }
            }

            DrawOrderIndex.Insert(i, Items.IndexOf(component));
        }

        /// <summary>
        /// 该组件集合的枚举器
        /// </summary>
        public ComponentEnumerator ListDrawOrder
        {
            get
            {
                return new ComponentEnumerator(this, this.DrawOrderIndex);
            }
        }

        /// <summary>
        /// 从第index(>=0)个位置移除一个元素
        /// </summary>
        /// <param name="index"></param>
        protected override void RemoveItem(int index)
        {
            Items[index].Parent = null;
            Items[index].DrawOrderChanged -= item_DrawOrderChanged;
            base.RemoveItem(index);
            this.DrawOrderIndex.Clear();
            //重建绘制顺序索引表
            foreach (Component component in Items)
            {
                this.UpdateDrawPosition(component);
            }
        }
    }
}
